#ifndef WL_EXT_OPUS_H
#define WL_EXT_OPUS_H

typedef void* wl_ext_opus_encoder_handle;
typedef void* wl_ext_opus_decoder_handle;

/**
 * 接口基本是封装开源opus的接口，只是提前做了一些参数设置
 * 建议使用者在实现的时候，先做好参数设置
 */


/**
 * Initialize the opus library
 * 
 * @param baudRate baud rate
 * @return 0 on success, < 0 on error
 *  
 */
int wl_ext_opus_init(int baudRate);

/**
 * Create a opus encoder
 * 
 * @param sampleRate sample rate
 * @return opus encoder handle
 */
wl_ext_opus_decoder_handle wl_ext_opus_create_decoder(int sampleRate);

/**
 * Create a opus decoder, implement should set parameters as follow before return handler
 * OPUS_SET_BITRATE(12000)
 * OPUS_SET_COMPLEXITY(2)
 * OPUS_SET_VBR(0)
 * OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)
 * OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)
 * OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)
 * 上面的参数，是实现者需要预先设定好
 * 
 * @param sampleRate sample rate
 * @return opus decoder handle
 *  
 */
wl_ext_opus_encoder_handle wl_ext_opus_create_encoder(int sampleRate);

/**
 * Encode pcm to opus
 * 
 * @param encoder opus encoder handle
 * @param pcm pcm data
 * @param frames 
 *   Number of samples per channel in the input signal.
 *   This must be an Opus frame size for the encoder's sampling rate.
 *   For example, at 48 kHz the permitted values are 120, 240, 480, 960, 1920,
 *   and 2880.Passing in a duration of less than 10 ms (480 samples at 48 kHz) will
 *   prevent the encoder from using the LPC or hybrid modes.
 * @param opus opus data
 * @param maxOpusSizeInBytes max opus size in bytes
 * @return 0 on success, < 0 on error
 */
int wl_ext_opus_encode(wl_ext_opus_encoder_handle encoder, const unsigned char* pcm, int frames, unsigned char* opus, int maxOpusSizeInBytes);

/**
 *  Decode opus to pcm
 * 
 * @param decoder opus decoder handle   
 * @param opus opus data
 * @param opusSizeInBytes opus size in bytes
 * @param pcm pcm data
 * @param frames
 * Number of samples per channel of available space in \a pcm.
 *  If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
 *  not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
 *  then frame_size needs to be exactly the duration of audio that is missing, otherwise the
 *  decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
 *  FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
 * @return 0 on success, < 0 on error
 */
int wl_ext_opus_decode(wl_ext_opus_decoder_handle decoder, const unsigned char* opus, int opusSizeInBytes, unsigned char* pcm, int frames);

/**
 * Destroy an opus encoder or decoder
 * 
 * @param encoder opus encoder handle
 * @return void
 */
void wl_ext_opus_destroy_encoder(wl_ext_opus_encoder_handle encoder);

/**
 * Destroy an opus decoder
 * 
 * @param decoder opus decoder handle
 * @return void
 * 
 */
void wl_ext_opus_destroy_decoder(wl_ext_opus_decoder_handle decoder);

/**
 * Deinitialize the opus library
 * 
 * @return void
 */
void wl_ext_opus_deinit(void);
#endif
